package com.zzx.utils;

//import cn.hutool.core.date.DateUtil;
//import cn.hutool.jwt.JWT;
//import cn.hutool.jwt.JWTPayload;
//import cn.hutool.jwt.JWTUtil;
//import cn.hutool.jwt.signers.JWTSignerUtil;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT工具类
 */

@Slf4j
public class JWTUtil {

    private static final String signature = "1qws2wed";

    /***
     * 生成token
     */
    public static String createToken(Map<String, Object> map) {
        Calendar instance = Calendar.getInstance();
//        instance.add(Calendar.DATE, 7); //设置过期时间7天
        instance.add(Calendar.YEAR, 1); //设置过期时间1年
//        instance.add(Calendar.MILLISECOND, 1000 * 60 * 60 * 24); //设置过期时间1天
        JWTCreator.Builder builder = JWT.create();
        map.forEach((k, v) -> {
            if (v instanceof String) {
                builder.withClaim(k, (String) v);
            } else if (v instanceof Integer) {
                builder.withClaim(k, (Integer) v);
            } else if (v instanceof Long) {
                builder.withClaim(k, (Long) v);
            } else if (v instanceof Double) {
                builder.withClaim(k, (Double) v);
            } else if (v instanceof Boolean) {
                builder.withClaim(k, (Boolean) v);
            } else if (v instanceof Date) {
                builder.withClaim(k, (Date) v);
            } else {
                // 对于非标准类型，转成 String 避免报错
                builder.withClaim(k, v.toString());
            }
        });
        String token = builder.withExpiresAt(instance.getTime())
                .sign(Algorithm.HMAC256(signature));
        return token;
    }

    /**
     * 获取token过期时间
     * @param token
     * @return
     */
    public static Date getTokenExpiryDate(String token) {
        DecodedJWT decodedJWT = JWT.decode(token); // 解码 token
        return decodedJWT.getExpiresAt(); // 获取过期时间
    }
    /***
     * 验证token
     */
    public static boolean verifyToken(String token) {
        try {
            JWT.require(Algorithm.HMAC256(signature)).build().verify(token);
        } catch (NullPointerException e) {
            return false;
        } catch (TokenExpiredException e) {
            return false;
        } catch (SignatureVerificationException e) {
            return false;
        } catch (JWTVerificationException e) {
            return false;
        } catch (IllegalArgumentException e) {
            return false;
        }
        return true;
    }

    /***
     * 获取token信息
     */
    public static Map<String, Object> getTokenInfo(String token) {
        DecodedJWT verify = null;
        try {
            verify = JWT.require(Algorithm.HMAC256(signature)).build().verify(token);
        } catch (NullPointerException e) {
            throw new RuntimeException("token不能为空!", e);
        } catch (TokenExpiredException e) {
            throw new RuntimeException("token过期!", e);
        } catch (SignatureVerificationException e) {
            throw new RuntimeException("签名验证失败!", e);
        } catch (JWTVerificationException e) {
            throw new RuntimeException("token验证失败!",e);
        } catch (IllegalArgumentException e) {
            throw new RuntimeException(e);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("openId", verify.getClaim("openId").asString());
        map.put("sessionKey", verify.getClaim("sessionKey").asString());
        map.put("userId", verify.getClaim("userId").asLong());
        map.put("userCategory", verify.getClaim("userCategory").asInt());
        map.put("companyId", verify.getClaim("companyId").asLong());
        return map;
    }

    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", "李白");
        map.put("age", "10");
//        DecodedJWT tokenInfo = getTokenInfo(createToken(map));
//        String name = tokenInfo.getClaim("name").asString();
//        String age = tokenInfo.getClaim("age").asString();
//        Map<String, Claim> claims = tokenInfo.getClaims();
//        System.out.println(name);
//        System.out.println(age);
    }
}
